//
//  PSFilterDeclarerFirstHandMoveOpen.m
//  PrefCore
//
//  Created by Sergey on 6/13/14.
//  Copyright (c) 2014 Play-on-smart. All rights reserved.
//

#import "PSFilter.h"
#import "PSGame.h"

static BOOL CanMoveWithHighestTrump(
    PSCardRankSet t
,   PSCardRankSet t1
,   PSCardRankSet t2
) {
    while (t != 0 && (t1 != 0 || t2 != 0)) {
        PSCardRank h  = PSCardSetHighestRank(t);
        PSCardRank h1 = PSCardSetNextHigherRank(t1, h);
        PSCardRank l1 = PSCardSetLowestRank(t1);
        PSCardRank h2 = PSCardSetNextHigherRank(t2, h);
        PSCardRank l2 = PSCardSetLowestRank(t2);
        
        // even if one of the opponents has trump higher than declarer's highest one,
        // declarer can move with the highest trump if his trump's suit length greater by more than 1
        // opponent's having longest trump suit
        if ((h1 != kRankNull || h2 != kRankNull) && PSHandGetSize(t) - MAX(PSHandGetSize(t1), PSHandGetSize(t2)) < 2) {
            return NO;
        }
        t = PSHandRemoveHand(t, PSCardRankHash(h));
        if (l1 != kRankNull) {
            t1 = PSHandRemoveHand(t1, PSCardRankHash(l1));
        }
        if (l2 != kRankNull) {
            t2 = PSHandRemoveHand(t2, PSCardRankHash(l2));
        }
    }
    return YES;
}

PSHandHash PSFilterDeclarerFirstHandMoveOpen(
    PSHandHash candidates
,   PSCardSuit trump
,   PSPlayerId declarer
,   PSHandHash* hands
) {
    // get trump suit
    PSCardRankSet t = PSHandGetSuit(candidates, trump);
    if (!PSCardSetSize(t)) {
        return candidates;
    }
    // resolve opponents and their trump suits
    PSPlayerId p1 = PSGameNextPlayerId(declarer);
    PSCardRankSet t1 = PSHandGetSuit(hands[p1], trump);
    PSPlayerId p2 = PSGameNextPlayerId(p1);
    PSCardRankSet t2 = PSHandGetSuit(hands[p2], trump);
    // if declarer has trump cards but opponents don't then all trump candidates can be removed
    if (PSCardSetSize(t1) + PSCardSetSize(t2) == 0) {
        return PSHandRemoveHand(candidates, trump);
    }
    if (CanMoveWithHighestTrump(t, t1, t2)) {
        return PSHandWithOneCard([PSCard cardWithSuit:trump andRank:PSCardSetHighestRank(t)]);
    }
    return candidates;
}
